package com.rushb.msg.utils;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class HttpClientUtil {

    private final static Logger LOGGER = LoggerFactory.getLogger(HttpClientUtil.class);

    private HttpClientUtil() {
    }

    // 连接主机超时（30s）
    private static final int HTTP_CONNECT_TIMEOUT_30S = 30 * 1000;

    // 从主机读取数据超时（30s）
    private static final int HTTP_READ_TIMEOUT = 30 * 1000;

    private static final String DEFAULT_CHARSET_ENCODE = "utf-8";

    public static String httpPost(String url, String jsonParam) throws IOException {
        return httpPost(url, jsonParam, DEFAULT_CHARSET_ENCODE, null);
    }


    public static String httpPost(String url, String jsonParam, String charset) throws IOException {
        return httpPost(url, jsonParam, charset, null);
    }

    /**
     * httpPost 默认传递的为json格式的报文
     * modify by ceb
     * descript add headers，param of map
     */
    public static String httpPost(String url, String jsonParam, Map<String, String> headers) throws IOException {
        return httpPost(url, jsonParam, DEFAULT_CHARSET_ENCODE, headers);
    }

    /**
     * httpPost 默认传递的为json格式的报文
     * modify by ceb
     * descript add headers，param of map
     */
    public static String httpPost(String url, String jsonParam, String charset, Map<String, String> headers) throws IOException {
        return httpPost(url, jsonParam, DEFAULT_CHARSET_ENCODE, headers, null);
    }

    public static String httpPost(String url, String jsonParam, String charset, Map<String, String> headers, String contentType) throws IOException {

        if (StringUtils.isBlank(charset)) {
            charset = DEFAULT_CHARSET_ENCODE;
        }
        if (StringUtils.isBlank(contentType)) {
            contentType = "application/json";
        }
        CloseableHttpClient httpclient = null;
        CloseableHttpResponse response = null;
        try {
            httpclient = HttpClients.createDefault();
            HttpPost httpPost = new HttpPost(url);

            // 设置请求头和请求参数
            if (null != jsonParam && !jsonParam.isEmpty()) {
                StringEntity entity = new StringEntity(jsonParam, charset);
                //entity.setContentEncoding(charset);
                entity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json;charset=utf-8"));
                entity.setContentType(contentType);
                httpPost.setEntity(entity);
            }

            // 超时时间设置
            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(HTTP_READ_TIMEOUT)
                    .setConnectTimeout(HTTP_CONNECT_TIMEOUT_30S).build();
            httpPost.setConfig(requestConfig);

            //设置header属性
            if (headers != null && headers.size() > 0) {
                for (Map.Entry<String, String> entity : headers.entrySet()) {
                    httpPost.addHeader(entity.getKey(), entity.getValue());
                }
            }

            // 发送请求
            response = httpclient.execute(httpPost);

            if (response.getStatusLine().getStatusCode() != 200) {
                LOGGER.error("url:" + url + " response statusLine:" + response.getStatusLine().toString());
            }

            // 获取返回内容
            HttpEntity entity = response.getEntity();
            String str = EntityUtils.toString(entity);
            // 此句关闭了流
            EntityUtils.consume(entity);
            return str;
        } finally {
            if (httpclient != null) {
                httpclient.close();
            }
            if (response != null) {
                response.close();
            }

        }
    }


    public static String httpPost(String url, Map<String, String> jsonParam, String charset, Map<String, String> headers, String contentType) throws IOException {

        if (StringUtils.isBlank(charset)) {
            charset = DEFAULT_CHARSET_ENCODE;
        }
        if (StringUtils.isBlank(contentType)) {
            contentType = "application/json";
        }
        CloseableHttpClient httpclient = null;
        CloseableHttpResponse response = null;
        try {
            httpclient = HttpClients.createDefault();
            HttpPost httpPost = new HttpPost(url);

            // 设置请求头和请求参数
            if (null != jsonParam && jsonParam.size() > 0) {
                List<BasicNameValuePair> params = new ArrayList<>(jsonParam.size());
                for (Map.Entry<String, String> entity : jsonParam.entrySet()) {
                    params.add(new BasicNameValuePair(entity.getKey(), entity.getValue()));
                }
                UrlEncodedFormEntity from = new UrlEncodedFormEntity(params, charset);
                httpPost.setEntity(from);
            }

            // 超时时间设置
            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(HTTP_READ_TIMEOUT)
                    .setConnectTimeout(HTTP_CONNECT_TIMEOUT_30S).build();
            httpPost.setConfig(requestConfig);

            //设置header属性
            if (headers != null && headers.size() > 0) {
                for (Map.Entry<String, String> entity : headers.entrySet()) {
                    httpPost.addHeader(entity.getKey(), entity.getValue());
                }
            }

            // 发送请求
            response = httpclient.execute(httpPost);
            // 获取返回内容
            if (response.getStatusLine().getStatusCode() != 200) {
                LOGGER.error("url:" + url + " response statusLine:" + response.getStatusLine().toString());
            }

            HttpEntity entity = response.getEntity();
            String str = EntityUtils.toString(entity);
            // 此句关闭了流
            EntityUtils.consume(entity);
            return str;
        } finally {
            if (httpclient != null) {
                httpclient.close();
            }
            if (response != null) {
                response.close();
            }

        }
    }

    /**
     * httpGet
     */
    public static String httpGet(String url) throws IOException {
        return httpGet(url, null);
    }

    /**
     * httpGet
     */
    public static String httpGet(String url, Map<String, String> headers) throws IOException {
        return httpGet(URI.create(url), headers);
    }

    /**
     * httpGet
     */
    public static String httpGet(URI uri, Map<String, String> headers) throws IOException {
        CloseableHttpClient httpclient = null;
        CloseableHttpResponse response = null;
        try {
            httpclient = HttpClients.createDefault();
            HttpGet httpGet = new HttpGet(uri);

            // 超时时间设置
            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(HTTP_READ_TIMEOUT)
                    .setConnectTimeout(HTTP_CONNECT_TIMEOUT_30S).build();
            httpGet.setConfig(requestConfig);

            //设置header属性
            if (headers != null && headers.size() > 0) {
                for (Map.Entry<String, String> entity : headers.entrySet()) {
                    httpGet.addHeader(entity.getKey(), entity.getValue());
                }
            }
            // 发送请求
            response = httpclient.execute(httpGet);

            if (response.getStatusLine().getStatusCode() != 200) {
                LOGGER.error("url:" + uri + " response statusLine:" + response.getStatusLine().toString());
                LOGGER.error("url:" + uri + " response statusLine:" + response.getAllHeaders());
            }

            // 获取返回内容
            HttpEntity entity = response.getEntity();

            return EntityUtils.toString(entity);
        } finally {
            if (httpclient != null) {
                httpclient.close();
            }
            if (response != null) {
                response.close();
            }
        }
    }


    public static String httpDelete(String url, String jsonParam) throws IOException {
        return httpDelete(url, jsonParam, DEFAULT_CHARSET_ENCODE);
    }


    public static String httpDelete(String url, String jsonParam, String charset) throws IOException {
        return httpDelete(url, jsonParam, charset, null, null);
    }

    /**
     * httpPost 默认传递的为json格式的报文
     * modify by ceb
     * descript add headers，param of map
     */
    public static String httpDelete(String url, String jsonParam, Map<String, String> headers) throws IOException {
        return httpDelete(url, jsonParam, DEFAULT_CHARSET_ENCODE, headers, null);
    }

    public static String httpDelete(String url, String jsonParam, String charset, Map<String, String> headers) throws IOException {
        return httpDelete(url, jsonParam, charset, headers, null);
    }

    public static String httpDelete(String url, String jsonParam, String charset, Map<String, String> headers, String contentType) throws IOException {
        if (StringUtils.isBlank(charset)) {
            charset = DEFAULT_CHARSET_ENCODE;
        }
        if (StringUtils.isBlank(contentType)) {
            contentType = "application/json";
        }
        CloseableHttpClient httpclient = null;
        CloseableHttpResponse response = null;
        try {
            httpclient = HttpClients.createDefault();
            HttpDeleteWithBody httpDelete = new HttpDeleteWithBody(url);

            // 设置请求头和请求参数
            if (null != jsonParam && !jsonParam.isEmpty()) {
                StringEntity entity = new StringEntity(jsonParam, charset);
                entity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json;charset=utf-8"));
                entity.setContentType("application/json");
                httpDelete.setEntity(entity);
            }

            // 超时时间设置
            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(HTTP_READ_TIMEOUT)
                    .setConnectTimeout(HTTP_CONNECT_TIMEOUT_30S).build();
            httpDelete.setConfig(requestConfig);

            //设置header属性
            if (headers != null && headers.size() > 0) {
                for (Map.Entry<String, String> entity : headers.entrySet()) {
                    httpDelete.addHeader(entity.getKey(), entity.getValue());
                }
            }

            // 发送请求
            response = httpclient.execute(httpDelete);
            // 获取返回内容
            if (response.getStatusLine().getStatusCode() != 200) {
                LOGGER.error("url:" + url + " response statusLine:" + response.getStatusLine().toString());
                LOGGER.error("url:" + url + " response statusLine:" + response.getAllHeaders());
            }
            HttpEntity entity = response.getEntity();
            String str = EntityUtils.toString(entity);
            // 此句关闭了流
            EntityUtils.consume(entity);
            return str;
        } finally {
            if (httpclient != null) {
                httpclient.close();
            }
            if (response != null) {
                response.close();
            }

        }
    }


    public static String httpPatch(String url, String jsonParam) throws IOException {
        return httpPatch(url, jsonParam, DEFAULT_CHARSET_ENCODE);
    }


    public static String httpPatch(String url, String jsonParam, String charset) throws IOException {
        return httpPatch(url, jsonParam, charset, null, null);
    }

    /**
     * httpPost 默认传递的为json格式的报文
     * modify by ceb
     * descript add headers，param of map
     */
    public static String httpPatch(String url, String jsonParam, Map<String, String> headers) throws IOException {
        return httpPatch(url, jsonParam, DEFAULT_CHARSET_ENCODE, headers, null);
    }

    public static String httpPatch(String url, String jsonParam, String charset, Map<String, String> headers) throws IOException {
        return httpPatch(url, jsonParam, charset, headers, null);
    }

    public static String httpPatch(String url, String jsonParam, String charset, Map<String, String> headers, String contentType) throws IOException {
        if (StringUtils.isBlank(charset)) {
            charset = DEFAULT_CHARSET_ENCODE;
        }
        if (StringUtils.isBlank(contentType)) {
            contentType = "application/json";
        }
        CloseableHttpClient httpclient = null;
        CloseableHttpResponse response = null;
        try {
            httpclient = HttpClients.createDefault();
            HttpPatch httpPatch = new HttpPatch(url);

            // 设置请求头和请求参数
            if (null != jsonParam && !jsonParam.isEmpty()) {
                StringEntity entity = new StringEntity(jsonParam, charset);
                entity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json;charset=utf-8"));
                entity.setContentType("application/json");
                httpPatch.setEntity(entity);
            }

            // 超时时间设置
            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(HTTP_READ_TIMEOUT)
                    .setConnectTimeout(HTTP_CONNECT_TIMEOUT_30S).build();
            httpPatch.setConfig(requestConfig);

            //设置header属性
            if (headers != null && headers.size() > 0) {
                for (Map.Entry<String, String> entity : headers.entrySet()) {
                    httpPatch.addHeader(entity.getKey(), entity.getValue());
                }
            }

            // 发送请求
            response = httpclient.execute(httpPatch);
            // 获取返回内容

            HttpEntity entity = response.getEntity();
            String str = EntityUtils.toString(entity);
            // 此句关闭了流
            EntityUtils.consume(entity);
            return str;
        } finally {
            if (httpclient != null) {
                httpclient.close();
            }
            if (response != null) {
                response.close();
            }

        }
    }

}
